package com.inspur.edp.formserver.vmmanager.util;

import com.inspur.edp.bef.bizentity.common.BizEntityJsonConst;
import com.inspur.edp.bef.bizentity.pushchangesetargs.ActionChangeDetail;
import com.inspur.edp.bef.bizentity.util.StringUtil;
import com.inspur.edp.das.commonmodel.json.CommonModelNames;
import com.inspur.edp.formserver.viewmodel.GspViewModel;
import com.inspur.edp.formserver.viewmodel.action.IViewModelParameter;
import com.inspur.edp.formserver.viewmodel.action.IViewModelParameterCollection;
import com.inspur.edp.formserver.viewmodel.action.ViewModelAction;
import com.inspur.edp.formserver.viewmodel.action.viewmodelbase.ViewModelParameter;
import com.inspur.edp.formserver.viewmodel.collection.VMActionCollection;
import com.inspur.edp.formserver.viewmodel.common.VMCollectionParameterType;
import com.inspur.edp.formserver.viewmodel.common.VMParameterType;
import com.inspur.edp.formserver.viewmodel.exception.ViewModelException;
import com.inspur.edp.formserver.vmmanager.exception.VoManagerErrorCodes;
import com.inspur.edp.lcm.metadata.api.entity.GspMetadata;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PushActionChangeSet {

    public PushActionChangeSet() {
    }

    /**
     * 根据动作ID获取自定义动作
     *
     * @param metadata
     * @param id
     * @return
     */
    public ViewModelAction getMgrActionByID(GspMetadata metadata, String id) {
        GspViewModel entity = (GspViewModel) metadata.getContent();
        if (entity.getActions() == null | entity.getActions().size() == 0) {
            return null;
        }
        List<ViewModelAction> result = entity.getActions().stream().filter(action ->
                action.getMapping() != null &&
                        !StringUtil.checkNull(action.getMapping().getTargetObjId()) &&
                        action.getMapping().getTargetObjId().equals(id)).collect(
                Collectors.toList());

        if (result.size() < 1)
            return null;
        return result.get(0);
    }

    /**
     * 新增自定义动作
     *
     * @param metadata
     * @param action
     */
    public void AddMgrAction(GspMetadata metadata, ViewModelAction action) {
        VMActionCollection vmActions = ((GspViewModel) metadata.getContent()).getActions();
        if (vmActions.stream().anyMatch(item -> item.getCode().equals(action.getCode()))) {
            return;
        }
        vmActions.add(action);
    }

    /**
     * 新增动作参数
     *
     * @param orgAction
     * @param refAction
     */
    public void addMgrActionParam(ViewModelAction orgAction, ViewModelAction refAction, String parameterCode) {
        if (refAction.getParameterCollection() == null || refAction.getParameterCollection().size() == 0) {
            return;
        }
        IViewModelParameterCollection orgParams = orgAction.getParameterCollection();

        if (orgParams.stream().anyMatch(item -> ((ViewModelParameter) item).getParamCode().equals(parameterCode))) {
            return;
        }

        refAction.getParameterCollection().forEach(item -> {
            if (((ViewModelParameter) item).getParamCode().equals(parameterCode)) {
                orgAction.getParameterCollection().add(item);
            }
        });
    }


    /**
     * 修改自定义动作
     *
     * @param destAction
     * @param refAction
     * @param changeDetail
     */
    public void ModifyAction(ViewModelAction destAction, ViewModelAction refAction, ActionChangeDetail changeDetail) {
        Map<String, Object> changeInfo = changeDetail.getChangeInfo();
//    String parameterCode = changeDetail.getParameterCode();
        if (destAction == null) {
            return;
        }
        changeInfo.forEach((key, val) -> {
            modifyActionPropertyValue(key, val, destAction, refAction, changeDetail);
        });
    }

    private void modifyActionPropertyValue(String propertyName, Object propertyValue, ViewModelAction destAction, ViewModelAction refAction, ActionChangeDetail changeDetail) {
        if (destAction == null) {
            return;
        }
        String parameterCode = changeDetail.getParameterCode();
        switch (propertyName) {
            case CommonModelNames.Code:
                destAction.setCode((String) propertyValue);
                break;
            case BizEntityJsonConst.ReturnValue:
                if (refAction == null) {
                    return;
                }
                destAction.setReturnValue(refAction.getReturnValue());
                break;
            case BizEntityJsonConst.CollectionParameterType:
                modifyCollectionParameterType((Integer) propertyValue, destAction, parameterCode);
                break;
            case BizEntityJsonConst.ParamCode:
                modifyParamCode((String) propertyValue, destAction, parameterCode);
                changeDetail.setParameterCode((String) propertyValue);
                break;

            case BizEntityJsonConst.JavaClassName:
                modifyJavaClassName((String) propertyValue, destAction, parameterCode);
                break;

            case BizEntityJsonConst.ParameterType:
                modifyParameterType((Integer) propertyValue, destAction, parameterCode);
                break;
            default:
                throw new ViewModelException(VoManagerErrorCodes.GSP_VIEWOBJECT_MANAGER_0071, null, propertyName, destAction.getCode(), destAction.getName());
        }

    }

    /**
     * 修改动作参数
     *
     * @param newCode
     * @param action
     * @param parameterCode
     */
    private void modifyParamCode(String newCode, ViewModelAction action, String parameterCode) {
        for (Object item : action.getParameterCollection()) {
            if (((ViewModelParameter) item).getParamCode().equals(parameterCode)) {
                ((IViewModelParameter) item).setParamCode(newCode);
                break;
            }
        }
    }

    /**
     * 修改动作ClassName
     *
     * @param newClassName
     * @param action
     * @param parameterCode
     */
    private void modifyJavaClassName(String newClassName, ViewModelAction action, String parameterCode) {
        for (Object item : action.getParameterCollection()) {
            if (((ViewModelParameter) item).getParamCode().equals(parameterCode)) {
                ((IViewModelParameter) item).setClassName(newClassName);
                break;
            }
        }
    }

    /**
     * 修改动作参数类型
     *
     * @param newType
     * @param action
     * @param parameterCode
     */
    private void modifyParameterType(int newType, ViewModelAction action, String parameterCode) {
        for (Object item : action.getParameterCollection()) {
            if (((ViewModelParameter) item).getParamCode().equals(parameterCode)) {
                ((IViewModelParameter) item).setParameterType(VMParameterType.forValue(newType));
                break;
            }
        }
    }

    private void modifyCollectionParameterType(int newType, ViewModelAction action, String parameterCode) {
        for (Object item : action.getParameterCollection()) {
            if (((ViewModelParameter) item).getParamCode().equals(parameterCode)) {
                ((IViewModelParameter) item).setCollectionParameterType(VMCollectionParameterType.forValue(newType));
            }
        }
    }

    public void deleteMgrAction(GspMetadata metadata, String actionCode) {
        ((GspViewModel) metadata.getContent()).getActions().removeIf(act ->
                act.getCode().equals(actionCode));
    }

    public void deleteMgrActionPara(ViewModelAction action, String parameterCode) {
        if (action == null || StringUtil.checkNull(parameterCode)) {
            return;
        }
        action.getParameterCollection().removeIf(param -> ((ViewModelParameter) param).getParamCode().equals(parameterCode));
    }

}
